import socket
import threading
import time
import json


class Net():
    localIP: str = None
    broadcastingIP: str = None
    _isBroadcasting: bool = False
    _isWaitingPlayer: bool = False
    playerList: list[str] = None
    isPlaying: bool = False
    _scanning: bool = False

    @classmethod
    def init(cls):
        udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        try:
            udpSocket.connect(('39.106.74.34', 7777))
        except:
            pass
        cls.localIP = udpSocket.getsockname()[0]
        ipSplitList = cls.localIP.split('.')
        cls.broadcastingIP = ipSplitList[0]+'.' + \
            ipSplitList[1]+'.'+ipSplitList[2]+'.255'

        print(cls.localIP)
        udpSocket.close()

    @classmethod
    def _broadcastingRoom(cls, roomName: str):
        udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        while cls.isBroadcasting:
            udpSocket.sendto(json.dumps(obj={
                'method': 'broadcastRoom',
                'roomName': roomName
            }).encode('utf-8'),
                (cls.broadcastingIP, 7777))
            time.sleep(1)
        udpSocket.close()

    @classmethod
    def startBroadcastingRoom(cls, roomName: str):
        cls._isBroadcasting = True
        threading.Thread(target=cls._broadcastingRoom,
                         args=(roomName,)).start()

    @ classmethod
    def stopBroadcatingRoom(cls):
        cls._isBroadcasting = False

    @ classmethod
    def _waitingPlayers(cls):
        udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        udpSocket.bind(('', 7788))
        while cls._isWaitingPlayer:
            try:
                recv_data = udpSocket.recvfrom(1024)
                recv_msg = recv_data[0]
                recv_addr = recv_data[1]
                jsonObj = json.loads(recv_msg.decode('utf-8'))
                if jsonObj.method == 'join':
                    if recv_addr in cls.playerList:
                        continue
                    else:
                        cls.playerList.append(recv_addr)
            except:
                pass
        udpSocket.close()

    @classmethod
    def startWaitingPlayers(cls):
        cls._isWaitingPlayer = True
        threading.Thread(target=cls._waitingPlayers).start()

    @classmethod
    def stopWaitingPlayers(cls):
        cls._isWaitingPlayer = False

    @classmethod
    def scanRoom(cls):
        udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        udpSocket.bind(('', 7788))
        while cls._scanning:
            recv_data = udpSocket.recvfrom(1024)
            recv_msg = recv_data[0]
            recv_addr = recv_data[1]

    @classmethod
    def joinRoom(cls, addr: str):
        udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        udpSocket.sendto()

    # @classmethod
    # def sendMsg(cls, game):
    #     udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    #     udpSocket.sendto(json.dumps({
    #         'method': 'move',
    #         'x': game.site_x,
    #         'y': game.site_y,
    #     }).encode('utf-8'), ('192.168.43.118', 7789))
    #     print("send:", game.site_x, game.site_y)
    @classmethod
    def sendActions(cls, player):
        # print('开始发送')
        udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        udpSocket.sendto(json.dumps({
            'method': 'move',
            'x': player.x,
            'y': player.y,
            'speed': player.speed,
        }).encode('utf-8'), ('192.168.43.118', 7789))
        # print("send:", player.x, player.y)

    @classmethod
    def recvActions(cls, player):
        udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        udpSocket.bind(('', 7789))
        udpSocket.settimeout(5)
        # print('开始接收')
        # while cls._isPlaying:
        while cls.isPlaying:
            try:
                recv_data = udpSocket.recvfrom(1024)
                recv_msg = recv_data[0]
                recv_addr = recv_data[1]
                jsonObj = json.loads(recv_msg.decode('utf-8'))
                # print(jsonObj)
                if jsonObj['method'] == 'move':
                    player.x = jsonObj['x']
                    player.y = jsonObj['y']
                    player.speed = jsonObj['speed']
                    print("recv:", jsonObj['x'], jsonObj['y'])
            except:
                print('recv blank')
        # print('结束接收')


if __name__ == '__main__':
    Net.init()
